import React from "./react";
import ReactDOM from "./react-dom/client";
/* 

现在希望如果改变的是输入框的值，ChildButton组件并不依赖输入框的值，所以ChildButton不要重新渲染
要想让ChildButton不重新渲染有两个条件

*/
function ChildButton({ displayData, incrementCount }) {
  console.log("Rendering ChildButton");
  return <button onClick={incrementCount}>{displayData.count}</button>;
}
//  第一个条件需要使用React.memo    使用了React.memo之后返回一个新组件，这个新组件可以保证如果新组件的属性不变，则不需要得新渲染这个新组件
const MemoChildButton = React.memo(ChildButton);
function App() {
  console.log("Rendering App");
  const [username, setUsername] = React.useState("zhufeng");
  const [count, setCount] = React.useState(0);
  // 第二个条件需要使用React.useMemo 可以缓存对象，此对象可做到在App组件多次渲染执行的时候保持引用地址不变

  //      第二个参数是依赖值 的数组，当依赖数组中的值不变时，则会复用上一次的值，如果变化了，则重新计算新的对象

  const displayData = React.useMemo(() => ({ count }), [count]);

  // 第三个条件需要使用React.useCallback可以缓存回调函数callback,此函数会在App组件多次渲染执行的时候保持引用地址不变
  //      第二个参数是依赖值 的数组，当依赖数组中的值不变时，则会复用上一次的值，如果变化了，则重新计算新的对象

  //  光 使用 React.memo   ChildButton 还更新的原因是，{ count } setCount((count) => count + 1)，会随着 App 渲染而更新
  const incrementCount = React.useCallback(() => {
    setCount((count) => count + 1);
  }, [count]);
  return (
    <div>
      <input
        type="text"
        value={username}
        onChange={(event) => setUsername(event.target.value)}
      />
      <MemoChildButton
        displayData={displayData}
        incrementCount={incrementCount}
      />
    </div>
  );
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
